package com.jzo2o.customer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.CurrentUserInfo;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.StringUtils;
import com.jzo2o.customer.enums.CertificationStatusEnum;
import com.jzo2o.customer.mapper.WorkerCertificationAuditMapper;
import com.jzo2o.customer.model.domain.WorkerCertification;
import com.jzo2o.customer.model.domain.WorkerCertificationAudit;
import com.jzo2o.customer.model.dto.request.CertificationAuditReqDTO;
import com.jzo2o.customer.model.dto.request.WorkerCertificationAuditAddReqDTO;
import com.jzo2o.customer.model.dto.request.WorkerCertificationAuditPageQueryReqDTO;
import com.jzo2o.customer.model.dto.response.RejectReasonResDTO;
import com.jzo2o.customer.model.dto.response.WorkerCertificationAuditResDTO;
import com.jzo2o.customer.service.IServeProviderService;
import com.jzo2o.customer.service.IWorkerCertificationAuditService;
import com.jzo2o.customer.service.IWorkerCertificationService;
import com.jzo2o.mvc.utils.UserContext;
import com.jzo2o.mysql.utils.PageUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;

/**
 * @author wjh
 * @create 2024-04-27 14:32
 */
@Service
@Slf4j
public class WorkerCertificationAuditServiceImpl extends ServiceImpl<WorkerCertificationAuditMapper, WorkerCertificationAudit> implements IWorkerCertificationAuditService {
    
    @Resource
    private IWorkerCertificationService workerCertificationService;
    @Resource
    private IServeProviderService serveProviderService;

    @Override
    public void applyCertification(WorkerCertificationAuditAddReqDTO workerCertificationAuditAddReqDTO) {
        WorkerCertificationAudit workerCertificationAudit = BeanUtil.toBean(workerCertificationAuditAddReqDTO, WorkerCertificationAudit.class);
        workerCertificationAudit.setAuditStatus(0);
        save(workerCertificationAudit);
        //上面是给服务人员申请认证信息表添加数据的，如果认证失败，服务人员还可以再次申请，也就是一张表可以存多个同个服务人员的申请信息，它的主键不是服务人员id，所以可以有多个
        //那以后我们怎么获取当前服务人员是否已经认证了呢，所以还需要有一张表存储当前服务人员认证状态的信息，它和服务人员认证信息表是一对一关系。
        //所以如果服务人员没有认证信息，就创建一个，如果已经有了，就修改为0,表示初始化状态，因为这个方法就是申请认证的第一步，所以认证状态就是初始化
        WorkerCertification workerCertification = workerCertificationService.getById(workerCertificationAuditAddReqDTO.getServeProviderId());
        if (ObjectUtil.isNotNull(workerCertification)) {
            workerCertification.setCertificationStatus(CertificationStatusEnum.PROGRESSING.getStatus());
            workerCertificationService.updateById(workerCertification);
        } else {
            workerCertification = BeanUtil.toBean(workerCertificationAuditAddReqDTO, WorkerCertification.class);
            workerCertification.setId(workerCertificationAuditAddReqDTO.getServeProviderId());
            workerCertification.setCertificationStatus(CertificationStatusEnum.PROGRESSING.getStatus());
            workerCertificationService.save(workerCertification);
        }
    }

    @Override
    @Transactional
    public void auditCertification(Long id, CertificationAuditReqDTO certificationAuditReqDTO) {
        WorkerCertificationAudit workerCertificationAudit = getById(id);
        WorkerCertification workerCertification = workerCertificationService.getById(workerCertificationAudit.getServeProviderId());
        if (ObjectUtil.isNotNull(workerCertificationAudit)) {
            //如果是认证成功，就要设置认证成功的时间
            if (certificationAuditReqDTO.getCertificationStatus() == 2) {
                workerCertification.setCertificationTime(LocalDateTime.now());
                //还要修改服务人员/机构人员的名称
                serveProviderService.updateNameById(workerCertificationAudit.getServeProviderId(), workerCertificationAudit.getName());
            } else {
                //如果是驳回就设置驳回原因
                workerCertificationAudit.setRejectReason(certificationAuditReqDTO.getRejectReason());
                
            }
            //设置认证状态
            workerCertificationAudit.setCertificationStatus(certificationAuditReqDTO.getCertificationStatus());
            //设置审核状态,已审核
            workerCertificationAudit.setAuditStatus(1);
            //设置审核时间
            workerCertificationAudit.setAuditTime(LocalDateTime.now());
            CurrentUserInfo currentUserInfo = UserContext.currentUser();
            //设置审核人id
            workerCertificationAudit.setAuditorId(currentUserInfo.getId());
            //设置审核人名称
            workerCertificationAudit.setAuditorName(currentUserInfo.getName());
            //设置认证表中的认证状态
            workerCertification.setCertificationStatus(certificationAuditReqDTO.getCertificationStatus());
        } else {
            throw new ForbiddenOperationException("认证信息不存在");
        }
        //修改申请表中的数据
        updateById(workerCertificationAudit);
        //修改认证表中的数据
        workerCertificationService.updateById(workerCertification);
    }

    @Override
    public PageResult<WorkerCertificationAuditResDTO> pageQuery(WorkerCertificationAuditPageQueryReqDTO workerCertificationAuditPageQueryReqDTO) {
        Page<WorkerCertificationAudit> page = new Page<>(workerCertificationAuditPageQueryReqDTO.getPageNo(), workerCertificationAuditPageQueryReqDTO.getPageSize());
        String orderBy1 = workerCertificationAuditPageQueryReqDTO.getOrderBy1();
        String orderBy2 = workerCertificationAuditPageQueryReqDTO.getOrderBy2();
        
        if (StringUtils.isNotBlank(orderBy1)) {
            workerCertificationAuditPageQueryReqDTO.setOrderBy1(StringUtils.toUnderlineCase(orderBy1));
        }
        if (StringUtils.isNotBlank(orderBy2)) {
            workerCertificationAuditPageQueryReqDTO.setOrderBy2(StringUtils.toUnderlineCase(orderBy2));
        }
        baseMapper.pageQuery(page, workerCertificationAuditPageQueryReqDTO);
        return PageUtils.toPage(page, WorkerCertificationAuditResDTO.class);
    }

    @Override
    public RejectReasonResDTO queryCurrentUserLastRejectReason() {
        LambdaQueryWrapper<WorkerCertificationAudit> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WorkerCertificationAudit::getAuditStatus, 1)
                .eq(WorkerCertificationAudit::getCertificationStatus, 3)
                .eq(WorkerCertificationAudit::getServeProviderId, UserContext.currentUserId())
                .orderByDesc(WorkerCertificationAudit::getCreateTime)
                .last("limit 1");
        WorkerCertificationAudit workerCertificationAudit = getOne(queryWrapper);
        return new RejectReasonResDTO(workerCertificationAudit.getRejectReason());
    }
}
